 /*
 * UMLSynch - VPSDE plugin part
 * http://umlsynch.googlecode.com
 *
 * Copyright 2008-2010, Evgeny Alexeyev
 * Licensed under the EPL - v1.0
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */

package com.googlecode.umlsynch.vpsde.rpc_old.VPOperationServer;

import java.io.*;
import java.net.*;

import com.vp.plugin.ApplicationManager;



public class TVPOperationServerDispatcher { 
	IVPOperationServer classImplementation;
	ServerSocket server; 
	ObjectOutputStream outObjStream;
	ObjectInputStream inObjStream;
	Thread  operation = null;

	public TVPOperationServerDispatcher(IVPOperationServer ClassImplementation) {
		classImplementation = ClassImplementation;
		outObjStream = null;
		inObjStream = null;

		operation = new Thread(new Runnable () {
		  public void run () {
			try {
			    // Connect to the localhost: port 3129 
				server = new ServerSocket(3129, 0, InetAddress.getByName("localhost"));
			}
			catch(Exception e) {
				ApplicationManager.instance().getViewManager().showMessage("Serever socket open failed.");
			} 

			try	{
			  // accept and process client socket data 
			  do {
				ApplicationManager.instance().getViewManager().showMessage("Waiting for client socket accept");
				Socket s = server.accept();
				outObjStream = new ObjectOutputStream(s.getOutputStream());
				inObjStream = new ObjectInputStream(s.getInputStream());

				ApplicationManager.instance().getViewManager().showMessage("Get RPC method info.");
				
				String data = (String)inObjStream.readObject();
				
				ApplicationManager.instance().getViewManager().showMessage(":" + data);

				if (data.equals("GetWorkingArea")) {
				  GetWorkingArea(s);
				} 
				else if (data.equals("CreateClassOnDiagram")) {
				   CreateClassOnDiagram(s);
				}
				else if (data.equals("CreatePacketOnDiagram")) {
					CreatePacketOnDiagram(s);
				}
				else if (data.equals("CreateEnumOnDiagram")) {
					CreateEnumOnDiagram(s);
				}
				else if (data.equals("CloseEclipseConnection")) {
					s.close();
					break;
				} else {
					ApplicationManager.instance().getViewManager().showMessage("Unknown RPC method name: " + data);
				}
				s.close();
			} while (true);
					// close access for client socket 

			}
			catch(Exception e) {
				StackTraceElement[] stack = e.getStackTrace();
				if (stack.length > 0) { 
				ApplicationManager.instance().getViewManager()
				.showMessage("catch exception " + e.getStackTrace()[0].getFileName() + " Line:" + 
						e.getStackTrace()[0].getLineNumber());
				ApplicationManager.instance().getViewManager()
				.showMessage("Message: " + e.getMessage() + " class:" + e.getStackTrace()[0].getClassName()); 
				
				} else {
					ApplicationManager.instance().getViewManager()
					.showMessage("catch exception with unknown stack trace" + e.getMessage());
				}
			}			
		}
	});
		operation.start();
	}
	
	public void GetWorkingArea(Socket s) {
		// Read nothing from socket
		// Need to provide area info.  
		try {
		  VPWorkingAreaDescriptor wArea = classImplementation.GetWorkingArea();
		  if (wArea != null) {
		    outObjStream.writeObject(new String("VPWorkingAreaDescriptor"));		  			
		    outObjStream.writeObject(wArea);
		  }
		  else {
		    outObjStream.writeObject(new String("VPWorkingAreaDescriptorNull"));
		  } 
		} catch (IOException ex ){
		  ApplicationManager.instance().getViewManager().showMessage("catch exception " + ex.getMessage() );
		} 
		
	}

	public void CreatePacketOnDiagram(Socket s) {
		VPSDEPacketDescriptor mPacket = null;
		// Read PacketInfo from socket  

		String data;  

		try {
          data = (String)inObjStream.readObject();

		  if (data.equals("VPSDEPacketDescriptor")) {
			  mPacket = (VPSDEPacketDescriptor) inObjStream.readObject();
			  if (mPacket == null) {
				  ApplicationManager.instance().getViewManager().showMessage("Cant read VPSDEPacketDescriptor Object");
				  return;
			  }
          }
		  else {
			  ApplicationManager.instance().getViewManager().showMessage("Expected VPSDEPacketDescriptor argument:" + data);
			  return;
		  }
		  
          data = (String)inObjStream.readObject();
          VPPoint pt = null;
		  if (data.equals("VPPoint")) {
			  pt = (VPPoint) inObjStream.readObject();
			  if (pt == null) {
				  ApplicationManager.instance().getViewManager().showMessage("Cant read VPPoint Object");
				  return;
			  }
          }
		  else {
			  ApplicationManager.instance().getViewManager().showMessage("Expected VPPoint argument:" + data);
			  return;
		  }

		  classImplementation.CreatePacketOnDiagram(mPacket, pt);

		} catch (IOException ex ){
			ApplicationManager.instance().getViewManager().showMessage("IOException:" + ex.getMessage());
		} catch (ClassNotFoundException e) {
			ApplicationManager.instance().getViewManager().showMessage("ClassNotFoundException:" + e.getMessage());
		}	
	}
	private void CreateEnumOnDiagram(Socket s) {
		VPSDEEnumDescriptor mEnum = null;
		// Read PacketInfo from socket  

		String data = null;  

		try {
          data = (String)inObjStream.readObject();

		  if (data.equals("VPSDEEnumDescriptor")) {
			  mEnum = (VPSDEEnumDescriptor) inObjStream.readObject();
			  if (mEnum == null) {
				  ApplicationManager.instance().getViewManager().showMessage("Cant read VPSDEEnumDescriptor Object");
				  return;
			  }
          }
		  else {
			  ApplicationManager.instance().getViewManager().showMessage("Expected VPSDEEnumDescriptor argument:" + data);
			  return;
		  }
		  
          data = (String)inObjStream.readObject();
          VPPoint pt = null;
		  if (data.equals("VPPoint")) {
			  pt = (VPPoint) inObjStream.readObject();
			  if (pt == null) {
				  ApplicationManager.instance().getViewManager().showMessage("Cant read VPPoint Object");
				  return;
			  }
          }
		  else {
			  ApplicationManager.instance().getViewManager().showMessage("Expected VPPoint argument:" + data);
			  return;
		  }

		  classImplementation.CreateEnumOnDiagram(mEnum, pt);

		} catch (IOException ex ){
			ApplicationManager.instance().getViewManager().showMessage("IOException:" + ex.getMessage());
		} catch (ClassNotFoundException e) {
			ApplicationManager.instance().getViewManager().showMessage("ClassNotFoundException:" + e.getMessage());
		}		
	}
	
	public void CreateClassOnDiagram(Socket s) {
		VPSDEClassDescriptor mClass = null;
		// Read PacketInfo from socket  

		String data;  

		try {
  		  data = (String)inObjStream.readObject();

		  if (data.equals("VPSDEClassDescriptor")) {
			  mClass = (VPSDEClassDescriptor) inObjStream.readObject();
			  if (mClass == null) {
				  ApplicationManager.instance().getViewManager().showMessage("Cant read VPSDEClassDescriptor Object");
			  } else {
				  data = (String)inObjStream.readObject();
				  if (data.equals("VPPoint")) {
					  VPPoint pt  = (VPPoint) inObjStream.readObject();
					  if (pt != null) {
			            classImplementation.CreateClassOnDiagram(mClass, pt);
					  } 
					  else {
						  ApplicationManager.instance().getViewManager().showMessage("Cant read VPPoint Object");  
					  }
				  }
				  else {
					  ApplicationManager.instance().getViewManager().showMessage("Expected VPPoint: " + data);  
				  }
			  }
		  }
		  else {
			  ApplicationManager.instance().getViewManager().showMessage("Expected VPSDEClassDescriptor: " + data);  
		  }

		} catch (IOException ex ){
			ApplicationManager.instance().getViewManager().showMessage("IOException:" + ex.getMessage());
		} catch (ClassNotFoundException e) {
			ApplicationManager.instance().getViewManager().showMessage("ClassNotFoundException:" + e.getMessage());
		}	
	}
}  

